package net.cloudcodex.server.rpc;

import net.cloudcodex.server.Context;
import net.cloudcodex.server.data.AdvancedDAO;
import net.cloudcodex.server.data.Data;
import net.cloudcodex.server.service.CampaignService;
import net.cloudcodex.server.service.HomeService;
import net.cloudcodex.server.service.MessageService;
import net.cloudcodex.shared.dto.Result;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * Abstract RPC class, to provide utility methods.
 * 
 * @author Thomas.
 */
public class AbstractRPC extends RemoteServiceServlet {

	protected final DatastoreService datastore = 
		DatastoreServiceFactory.getDatastoreService();

	protected final AdvancedDAO dao = new AdvancedDAO(datastore);

	protected final HomeService homeService = new HomeService(datastore);

	protected final CampaignService campaignService = new CampaignService(datastore);

	protected final MessageService messageService = new MessageService(datastore);

	/**
	 * Try to find the current user in datastore.
	 * @return
	 */
	protected Data.User findCurrentUser() {
		
		// use appengine USerService.
		final UserService userService = UserServiceFactory.getUserService();
		final User guser = userService.getCurrentUser();

		if(guser == null) {
			return null;
		}
		
		final String userId = guser.getUserId();
		if(userId == null) {
			return null;
		}
		
		// Search the user with its google id.
		Data.User user = homeService.getUserByGoogleId(null, userId);

		if(user == null) {
			final String email = guser.getEmail();
			if(email == null) {
				return null;
			}
			
			// Search the user with its email.
			user = homeService.getUserByEmail(null, email);
		}
		
		return user;
	}
	
	/**
	 * Utility method to create a Context object.
	 * @return the context or null.
	 */
	protected Context createContext() {
		
		final Data.User user = findCurrentUser();
		return new Context(user);
	}
	
	protected <T> Result<T> createResult(Context context, T data) {
		return new Result<T>(!context.hasErrors(), context.getErrors(), data);
	}
}
